﻿//===============================================================================
// Magic OQL
//===============================================================================
// Copyright ?Magic Thought Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// Richie (http://www.cnblogs.com/RicCC)
// March 7, 2008
//===============================================================================

using Antlr.Runtime;

namespace SQLAnalyticLibrary.Expressions
{
    /// <summary>
    /// Table, column, and function name
    /// <remarks>
    /// </remarks>
    /// </summary>
    public class Identifier : Expression
    {
        /// <summary>
        /// 
        /// </summary>
        /// Identifier -> {new Identifier($Identifier)}
        /// All Identifier rewriting rules use the above style.
        /// <param name="t"></param>
       
        public Identifier(IToken t)
            : base(t)
        {
        }
        public override Expression DupNode()
        {
            return new Identifier(this.token);
        }
        public static bool IsIdentifier(Expression exp)
        {
            if (exp == null || exp.IsNil) return false;
            return exp.Token.Type == OQLParser.QuotedIdentifier || exp.Token.Type == OQLParser.NonQuotedIdentifier;
        }
        public string Name
        {
            get
            {
                return this.Text;
            }
        }

        public bool HasTableName
        {
            get
            {
                if (string.IsNullOrEmpty(this.Text) || this.Text.IndexOf('.') < 0) return false;
                return true;
            }
        }
        public string TableName
        {
            get
            {
                if (!this.HasTableName) return null;
                return this.Text.Substring(0, this.Text.LastIndexOf('.'));
            }
        }
        public bool HasColumnName
        {
            get
            {
                return !this.IsAllColumn;
            }
        }
        public string ColumnName
        {
            get
            {
                if (this.IsAllColumn) return null;
                if (!this.HasTableName)
                    return this.Text;
                int index = this.Text.LastIndexOf('.');
                return this.Text.Substring(index + 1);
            }
        }
        public bool IsAllColumn
        {
            get
            {
                return this.Text[this.Text.Length - 1] == '*';
            }
        }

        public override void VisitSql(ISqlVisitor visitor)
        {
            //Attention:
            //the following logic is only valide in a column like context, in a table like context it's just the table name.
            //the Table class will find out most table like context, and QueryStatement will pick up the remains. I'm not going to support table variables.
            //Column class will find out those column like context in select list, insert list, update list, etc. and the remains will arrive and be handled here.
            if (this.HasTableName) //try to identifier table name
            {
                visitor.Table(this.TableName);
                visitor.Sql(".");
            }
            if (this.IsAllColumn) visitor.Sql("*");
            else
                visitor.Column(this.TableName, this.ColumnName, false); //column name
        }

        internal static int TreeType
        {
            get
            {
                return OQLParser.NonQuotedIdentifier;
            }
        }
    }
}